#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;

class Time
{
public:
    Time(){  }
    Time(int h, int m, int s);
    friend Time operator+(const Time &t1, const Time &t2);
    friend ostream &operator<<(ostream &out, const Time &t);
private:
    int m_hour;
    int m_minute;
    int m_second;
};

Time::Time(int h, int m, int s)
{
    m_hour = h;
    m_minute = m;
    m_second = s;
}
Time operator+(const Time &t1, const Time &t2)
{
    Time t;
    t.m_hour = t1.m_hour + t2.m_hour;
    t.m_minute = t1.m_minute + t2.m_minute;
    t.m_second = t1.m_second + t2.m_second;
    return t;
}
ostream &operator<<(ostream &out, const Time &t)
{
    return out << "[" << t.m_hour << ":" << t.m_minute
            << ":" << t.m_second << "]" << endl;
}

///**************************************************///

char add(char a, char b)
{
    cout << "char add(char a, char b)" << endl;
    return a + b;
}

string add(string a, string b)
{
    cout << "string add(string a, string b)" << endl;
    return a + b;
}

Time add(Time a, Time b)
{
    cout << "Time add(Time a, Time b)" << endl;
    return a + b;
}

template <typename T>
T add(T a, T b)
{
    cout << "T add(T a, T b): " << sizeof(T) << endl;
    return a + b;
}

template <typename T, typename U>
T add(T a, U b)
{
    cout << "T add(T a, U b): " << sizeof(T) << sizeof(U) << endl;
    return a + b;
}

int main()
{
    cout << add('1', 2) << endl;
    cout << add('1', '2') << endl;
    cout << add(1, 2) << endl;
    cout << add(static_cast<float>(1.2), static_cast<float>(2.4)) << endl;
    cout << add(1.2222222222, 2.44444444444444) << endl;
    cout << add(string("hello"), string("world")) << endl;
    cout << add(Time(1,2,3), Time(4,5,6)) << endl;
    return 0;
}

